﻿using MesProjectWinform.Entity.Request;
using MesProjectWinform.Properties;
using Newtonsoft.Json;
using Qiniu.Http;
using Qiniu.Storage;
using Qiniu.Util;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MesProjectWinform.WareHouse.Helper
{

    public class QiNiuHelper
    {
        // 七牛云配置
        private static readonly string AccessKey = Settings.Default.AccessKey; // 这里使用系统配置中的AccessKey
        private static readonly string SecretKey = Settings.Default.SecretKey; // 这里使用系统配置中的SecretKey
        private static readonly string Bucket = "filezhanglala"; // 存储空间名称
        private static readonly string Domain = "sz0dgppo6.hb-bkt.clouddn.com"; // 访问域名
        //private static readonly bool IsPrivate = false; // 是否为私有空间

        public List<ListViewItem> FileModel;

        /// <summary>
        /// 上传文件到七牛云
        /// </summary>
        /// <param name="localFilePath">本地文件路径</param>
        /// <param name="saveFileName">保存在七牛云上的文件名</param>
        /// <returns>上传成功后的访问URL，失败则返回空字符串</returns>
        public static string UploadFile(string localFilePath, string saveFileName)
        {
            try
            {
                // 检查文件是否存在
                if (!File.Exists(localFilePath))
                {
                    return string.Empty;
                }

                // 构建保存的文件名，使用日期目录进行分类
                string saveKey = string.Format("Process/{0}/", DateTime.Now.ToString("yyyy/MM/dd")) + saveFileName;

                // 初始化上传凭证
                Mac mac = new Mac(AccessKey, SecretKey);
                PutPolicy putPolicy = new PutPolicy();
                
                // 设置上传的目标空间和文件名
                putPolicy.Scope = Bucket + ":" + saveKey;
                
                // 设置凭证有效期
                putPolicy.SetExpires(3600);
                
                // 生成上传凭证
                string jstr = putPolicy.ToJsonString();
                string token = Auth.CreateUploadToken(mac, jstr);

                // 创建上传管理器
                // 创建配置对象
                Config config = new Config();
                // 设置上传区域
                config.Zone = Zone.ZONE_CN_North;  // 根据错误信息修改为华北区域(up-z1.qiniup.com)
                // 是否使用https
                config.UseHttps = true;
                // 使用CDN加速
                config.UseCdnDomains = true;
                // 创建上传管理器并传入配置
                UploadManager um = new UploadManager(config);
                
                // 创建上传额外参数对象
                PutExtra extra = new PutExtra();
                
                // 执行上传操作
                HttpResult result = um.UploadFile(localFilePath, saveKey, token, extra);

                // 检查上传结果
                if (result.Code == 200)
                {
                    // 上传成功，返回文件的访问URL
                    return Domain + "/" + saveKey;
                }
                else
                {
                    System.Diagnostics.Debug.WriteLine($"七牛云上传失败：{result.Text}");
                    return string.Empty;
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"上传文件到七牛云时发生异常：{ex.Message}");
                return string.Empty;
            }
        }

        /// <summary>
        /// 从七牛云删除文件
        /// </summary>
        /// <param name="fileUrl">文件的完整URL</param>
        /// <returns>是否删除成功</returns>
        public static bool DeleteFile(string fileUrl)
        {
            try
            {
                // 如果URL为空，直接返回失败
                if (string.IsNullOrEmpty(fileUrl))
                {
                    return false;
                }

                // 从URL中提取文件key
                string key = ExtractKeyFromUrl(fileUrl);
                if (string.IsNullOrEmpty(key))
                {
                    System.Diagnostics.Debug.WriteLine("无法从URL中提取文件key");
                    return false;
                }

                // 初始化认证
                Mac mac = new Mac(AccessKey, SecretKey);
                
                // 创建配置对象
                Config config = new Config();
                config.Zone = Zone.ZONE_CN_North;  // 使用华北区域
                config.UseHttps = true;
                
                // 创建BucketManager对象
                BucketManager bucketManager = new BucketManager(mac, config);
                
                // 执行删除操作
                HttpResult deleteResult = bucketManager.Delete(Bucket, key);
                
                // 检查删除结果
                if (deleteResult.Code == 200 || deleteResult.Code == 612) // 612表示文件不存在，也视为删除成功
                {
                    System.Diagnostics.Debug.WriteLine($"七牛云文件删除成功：{key}");
                    return true;
                }
                else
                {
                    System.Diagnostics.Debug.WriteLine($"七牛云文件删除失败：{deleteResult.Text}, 错误码：{deleteResult.Code}");
                    return false;
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"删除七牛云文件时发生异常：{ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 从URL中提取文件key
        /// </summary>
        /// <param name="fileUrl">完整的文件URL</param>
        /// <returns>七牛云中的文件key</returns>
        private static string ExtractKeyFromUrl(string fileUrl)
        {
            try
            {
                // 确保URL不为空
                if (string.IsNullOrEmpty(fileUrl))
                {
                    return string.Empty;
                }

                // 如果URL包含域名，移除域名部分
                if (fileUrl.Contains(Domain))
                {
                    return fileUrl.Substring(fileUrl.IndexOf(Domain) + Domain.Length + 1); // +1 是为了去掉域名后的 "/"
                }
                
                // 如果URL不包含域名，直接返回URL作为key
                return fileUrl;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"提取文件key时发生异常：{ex.Message}");
                return string.Empty;
            }
        }

        /// <summary>
        /// 检查URL是否可访问
        /// </summary>
        /// <param name="url">需要检查的URL</param>
        /// <returns>URL是否有效</returns>
        private static bool CheckUrlValidity(string url)
        {
            try
            {
                // 忽略SSL证书错误
                ServicePointManager.ServerCertificateValidationCallback = 
                    (sender, certificate, chain, sslPolicyErrors) => true;
                
                // 确保支持所有TLS版本
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = "HEAD";
                request.Timeout = 5000; // 5秒超时
                
                try
                {
                    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                    {
                        return response.StatusCode == HttpStatusCode.OK;
                    }
                }
                catch (WebException webEx)
                {
                    // 检查是否为403错误，对七牛云来说可能意味着这是一个有效的资源但需要授权
                    if (webEx.Response is HttpWebResponse response && 
                        (response.StatusCode == HttpStatusCode.Forbidden || response.StatusCode == HttpStatusCode.Unauthorized))
                    {
                        // 403或401错误对七牛云私有空间是正常的，说明URL存在但需要授权
                        System.Diagnostics.Debug.WriteLine("文件需要授权访问，将继续尝试下载");
                        return true;
                    }
                    throw; // 其他网络错误则继续抛出
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"检查URL有效性时发生异常: {ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 从七牛云下载文件
        /// </summary>
        /// <param name="fileUrl">七牛云文件的URL或Key</param>
        /// <param name="savePath">本地保存路径，包含文件名</param>
        /// <param name="fileName">文件名，用于生成私有空间下载链接</param>
        /// <param name="IsPrivate">是否为私有空间，默认为false</param>
        /// <returns>是否下载成功</returns>
        public static bool DownloadFile(string fileUrl, string savePath, string fileName, bool IsPrivate=false)
        {
            try
            {
                // 检查URL是否为空
                if (string.IsNullOrEmpty(fileUrl))
                {
                    return false;
                }

                // 获取实际下载地址
                string downloadUrl = fileUrl;

                // 检查是否需要添加域名前缀
                if (!fileUrl.StartsWith("http"))
                {
                    // URL不包含协议头，可能只是文件key
                    string key = fileUrl;
                    downloadUrl = "http://"  + key;
                }

                // 检查是否为私有空间，如果是则需要对URL签名
                if (IsPrivate)
                {
                    Mac mac = new Mac(AccessKey, SecretKey);
                    string privateUrl = DownloadManager.CreatePrivateUrl(mac, downloadUrl, fileName, 3600);
                    downloadUrl = privateUrl;
                }

                // 检查URL是否可访问 - 注意：即使返回403，如果是私有空间的有效文件，这里也会返回true
                bool isUrlValid = CheckUrlValidity(downloadUrl);
                if (!isUrlValid)
                {
                    return false;
                }

                // 确保保存目录存在
                string saveDir = Path.GetDirectoryName(savePath);
                if (!Directory.Exists(saveDir))
                {
                    Directory.CreateDirectory(saveDir);
                }

                // 使用WebClient下载文件
                using (WebClient client = new WebClient())
                {
                    try
                    {
                        client.DownloadFile(downloadUrl, savePath);
                    }
                    catch (WebException webEx)
                    {
                        if (webEx.Response is HttpWebResponse response && 
                            response.StatusCode == HttpStatusCode.Forbidden && !IsPrivate)
                        {
                            // 如果收到403错误且未标记为私有空间，尝试作为私有空间处理
                            return DownloadFile(fileUrl, savePath, fileName, true);
                        }
                        throw;
                    }
                }

                // 验证文件是否已下载
                if (File.Exists(savePath))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (WebException webEx)
            {
                HttpWebResponse response = webEx.Response as HttpWebResponse;
               
                return false;
            }
            catch (Exception ex)
            {
                return false;
            }
        }
    }
}